﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Xml;
using com.lover.astd.common.manager;
using com.lover.astd.common.model;

namespace com.lover.astd.common.logic
{
    public class EquipMgr : MgrBase
    {
        public EquipMgr() { _logColor = System.Drawing.Color.Crimson; }

        #region store
        public List<Equipment> getStoreCanMelt(ProtocolMgr protocol, ILogger logger, User user)
        {
            getStore(protocol, logger, user);
            List<Equipment> total_eqps = user._storeEquips;
            List<Equipment> eqps = new List<Equipment>();
            for (int i = 0; i < total_eqps.Count; i++)
            {
                Equipment st = total_eqps[i];
                if (st.goodstype != GoodsType.Decoration && st.goodstype != GoodsType.Gem
                    && st.goodstype != GoodsType.Weapon)
                {
                    eqps.Add(st);
                }
            }
            return eqps;
        }
        public void getStore(ProtocolMgr protocol, ILogger logger, User user)
        {
            int used_size = 0, total_size = 0;
            List<Equipment> eqps = new List<Equipment>();
            string url = "/root/goods!openStorehouse.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取仓库信息");
            if (result == null || !result.CmdSucceed) return;
            XmlDocument xml = result.CmdResult;

            XmlNode cur_node = xml.SelectSingleNode("/results/usesize");
            if (cur_node != null) Int32.TryParse(cur_node.InnerText, out used_size);
            else used_size = 0;
            XmlNode max_node = xml.SelectSingleNode("/results/storesize");
            if (max_node != null) Int32.TryParse(max_node.InnerText, out total_size);
            else total_size = 0;

            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;

            foreach (XmlNode child in childs)
            {
                if (child.Name != "storehousedto") continue;
                Equipment st = new Equipment();
                XmlNodeList eqpchild_list = child.ChildNodes;
                st.fillValues(eqpchild_list);
                eqps.Add(st);
            }
            user._storeEquips = eqps;
            user._storeUsedSize = used_size;
            user._storeTotalSize = total_size;
        }
        /// <summary>
        /// 1=http error, 2=exceed limit silver, 3=到最低级, 4=unknown
        /// </summary>
        /// <returns></returns>
        public int degradeEquip(ProtocolMgr protocol, ILogger logger, int equipId)
        {
            string url = "/root/equip!degradeEquipByStore.action";
            string data = "storeId=" + equipId;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "降级装备");
            if (result == null) return 1;
            if (!result.CmdSucceed)
            {
                string cmderror = result.CmdError;
                if (cmderror.Contains("上限")) return 2;
                else if (cmderror.Contains("最低")) return 3;
                else return 4;
            }
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state><cost>363888</cost></results>
            XmlNode node = xml.SelectSingleNode("/results/cost");
            if (node != null) logInfo(logger, String.Format("降级成功, 银币+{0}", node.InnerText));

            return 0;
        }
        /// <summary>
        /// 1=http error, 2=exceed limit stone, 3=到最低级, 4=unknown
        /// </summary>
        /// <returns></returns>
        public int degradeMh(ProtocolMgr protocol, ILogger logger, int equipId)
        {
            string url = "/root/enchant!reduce.action";
            string data = "storeId=" + equipId;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "降魔装备");
            if (result == null) return 1;
            if (!result.CmdSucceed)
            {
                string cmderror = result.CmdError;
                if (cmderror.IndexOf("上限") >= 0) return 2;
                else if (cmderror.IndexOf("最低") >= 0) return 3;
                else return 4;
            }
            XmlDocument xml = result.CmdResult;
            XmlNode stone_node = xml.SelectSingleNode("/results/addbowlder");
            if (stone_node != null) logInfo(logger, String.Format("装备降魔成功, 玉石+{0}", stone_node.InnerText));

            return 0;
        }
        /// <summary>
        /// return 0=ok, 1=http error, 2=in campaign, 3=battle cd, 4=no order, 5=unknown
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public int meltEquip(ProtocolMgr protocol, ILogger logger, int equipId, int magic)
        {
            string url = "/root/stoneMelt!melt.action";
            string data = String.Format("magic={0}&gold=0&meltGold=0&storeId={1}", magic, equipId);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "融化装备");
            if (result == null) return 1;
            if (!result.CmdSucceed)
            {
                string cmderror = result.CmdError;
                if (cmderror.IndexOf("上限") >= 0) return 2;
                else if (cmderror.IndexOf("最低") >= 0) return 3;
                else return 4;
            }
            XmlDocument xml = result.CmdResult;
            XmlNode stone_node = xml.SelectSingleNode("/results/gainbowlder");
            if (stone_node != null) logInfo(logger, String.Format("装备融化成功, 玉石+{0}", stone_node.InnerText));
            return 0;
        }
        /// <summary>
        /// 卖出装备
        /// </summary>
        /// <param name="equipId"></param>
        /// <returns></returns>
        public int sellEquip(ProtocolMgr protocol, ILogger logger, int equipId)
        {
            string url = "/root/goods!sellGoods.action";
            string data = String.Format("goodsId={0}&count=1", equipId);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "卖出装备");
            if (result == null) return 1;
            if (!result.CmdSucceed)
            {
                string cmderror = result.CmdError;
                if (cmderror.IndexOf("上限") >= 0) return 2;
                else if (cmderror.IndexOf("最低") >= 0) return 3;
                else return 4;
            }
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state><usesize>15</usesize><cost>1000</cost></results>
            XmlNode node = xml.SelectSingleNode("/results/cost");
            if (node != null) logInfo(logger, String.Format("卖出装备成功, 银币+{0}", node.InnerText));
            return 0;
        }
        /// <summary>
        /// 收取在临时背包中的装备, return 0=success, 1=http failure, 2=not enough space
        /// </summary>
        /// <param name="equip"></param>
        /// <returns></returns>
        public int getEquip(ProtocolMgr protocol, ILogger logger, Equipment equip)
        {
            string url = "/root/goods!draw.action";
            string data = "";
            if (equip.goodstype == GoodsType.Gem) data = String.Format("baoshiLv={0}&count=1&goodsId=0", equip.Level);
            else data = String.Format("baoshiLv=0&count=1&goodsId={0}", equip.Id);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "拿取装备");
            if (result == null) return 1;
            if (!result.CmdSucceed)
            {
                if (result.CmdError.IndexOf("仓库没有足够的位置") >= 0) return 2;
                else return 1;
            }
            logInfo(logger, String.Format("从临时仓库拿取装备[{0}]", equip.Name));
            return 0;
        }
        /// <summary>
        /// 返回合成了多少个宝石
        /// </summary>
        /// <param name="gemLevel"></param>
        /// <returns></returns>
        public int mergeSameLevelGem(ProtocolMgr protocol, ILogger logger, int gemLevel)
        {
            string url = "/root/equip!updateBaoshiWholeLevel.action";
            string data = String.Format("baoshiId={0}", gemLevel);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "合成同级宝石" + gemLevel.ToString());
            if (result == null || !result.CmdSucceed) return 0;
            XmlDocument xml = result.CmdResult;
            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;
            int gemCount = 0, gemMergeCount = 0, gemInitLevel = 0, gemUpLevel = 0;
            foreach (XmlNode child in childs)
            {
                if (child.Name == "baoshilevel") gemInitLevel = Int32.Parse(child.InnerText);
                else if (child.Name == "num") gemCount = Int32.Parse(child.InnerText);
                else if (child.Name == "baoshilevelup") gemUpLevel = Int32.Parse(child.InnerText);
                else if (child.Name == "numup") gemMergeCount = Int32.Parse(child.InnerText);
            }
            string loginfo = String.Format("使用{0}级宝石{1}个, 合成{2}级宝石{3}个", gemLevel, gemCount, gemUpLevel, gemMergeCount);
            logInfo(logger, loginfo);
            return gemMergeCount;
        }
        #endregion

        #region polish
        /// <summary>
        /// 0=success, 1=http failure, 2=no suitable to polish,3=polish but not upgrade,4=attr upgrade, 10=other
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <param name="reserve_count">保留多少次</param>
        /// <param name="reserve_item_count">保留多少个, 其他直接融化, 节省背包</param>
        /// <param name="gold_merge_attrib">5次属性大于多少金币炼化</param>
        /// <param name="melt_failcount">几次不升级直接融化</param>
        /// <returns></returns>
        public int handlePolishInfo(ProtocolMgr protocol, ILogger logger, int gold_available,
            int magic_now, int reserve_count, int reserve_item_count,
            int gold_merge_attrib, int melt_failcount)
        {
            string url = "/root/polish!getBaowuPolishInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取炼化信息");
            if (result == null) return 1;
            if(!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            int _remain_melt_number = 0, _polish_level = 0;
            XmlNode remain_num_node = xml.SelectSingleNode("/results/num");
            if (remain_num_node != null) Int32.TryParse(remain_num_node.InnerText, out _remain_melt_number);

            XmlNode level_node = xml.SelectSingleNode("/results/level");
            if (level_node != null) Int32.TryParse(level_node.InnerText, out _polish_level);

            List<Decoration> _decorations = new List<Decoration>();
            XmlNodeList baowu_nodes = xml.SelectNodes("/results/baowu");
            foreach (XmlNode baowu_node in baowu_nodes)
            {
                Decoration dec = new Decoration();
                XmlNodeList child_nodes = baowu_node.ChildNodes;
                foreach (XmlNode child in child_nodes)
                {
                    if (child.Name == "storeid") dec.storeid = Int32.Parse(child.InnerText);
                    else if (child.Name == "attribute_base") dec.attribute_base = Int32.Parse(child.InnerText);
                    else if (child.Name == "polishtimes") dec.polishtimes = Int32.Parse(child.InnerText);
                    else if (child.Name == "gold") dec.gold = Int32.Parse(child.InnerText);
                    else if (child.Name == "name") dec.name = child.InnerText;
                }
                if (dec.polishtimes < 10) _decorations.Add(dec);
            }

            if (_remain_melt_number <= reserve_count) return 2;
            if (_decorations.Count == 0) return 2;
            // make sure only reserve <reserve_item_count> decorations
            int index = 0;
            while (_decorations.Count > 0 && _decorations.Count > reserve_item_count)
            {
                index = 0;
                foreach (Decoration dec in _decorations)
                {
                    // 查找第一个还没有炼化的玉佩, 防止将不想融化的融化掉, 如果都炼化了, 那么不融化
                    if (dec.polishtimes == 0) break;
                    index++;
                }
                if (index < _decorations.Count)
                {
                    Decoration dec_extra = _decorations[index];
                    destroy(protocol, logger, magic_now, dec_extra, true);
                    _decorations.RemoveAt(index);
                }
            }
            int base_attribute = 1; // 不到10级的炼化, 初始属性是1
            if (_polish_level >= 10) base_attribute = 2;// 10级的炼化, 初始属性是2
            foreach (Decoration dec in _decorations)
            {
                if (dec.polishtimes == 5)
                {
                    if (dec.attribute_base >= gold_merge_attrib)
                    {
                        int counter = _remain_melt_number;
                        // 因为polish函数中会改变_remain_melt_number的值, 所以这里事先保存下

                        while (_remain_melt_number > 0 && counter > 0 && gold_available > dec.gold)
                        {
                            gold_available -= dec.gold;
                            polish(protocol, logger, dec, out _remain_melt_number);
                            counter--;
                        }
                    }
                    else
                    {
                        destroy(protocol, logger, magic_now, dec, false);
                        return 0;
                    }
                }
                else if (dec.polishtimes < 5)
                {
                    if (dec.polishtimes >= melt_failcount && dec.attribute_base <= base_attribute)
                    {
                        destroy(protocol, logger, magic_now, dec, false);
                        return 0;
                    }
                    else
                    {
                        int attrib = polish(protocol, logger, dec, out _remain_melt_number);
                        if (attrib == 0) return 3;
                        else return 4;
                    }
                }
            }
            return 2;
        }
        public void qiling()
        {

        }
        /// <summary>
        /// 返回升了几点
        /// </summary>
        /// <param name="storeId"></param>
        /// <param name="userGold"></param>
        /// <returns></returns>
        public int polish(ProtocolMgr protocol, ILogger logger, Decoration dec, out int _remain_melt_number)
        {
            _remain_melt_number = 0;
            string url = "/root/polish!polish.action";
            string data = "storeId=" + dec.storeid;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "炼化");
            if (result == null || !result.CmdSucceed) return 0;
            XmlDocument xml = result.CmdResult;

            XmlNode remain_num_node = xml.SelectSingleNode("/results/num");
            if (remain_num_node != null) Int32.TryParse(remain_num_node.InnerText, out _remain_melt_number);

            XmlNode node = xml.SelectSingleNode("/results/baowu");
            Decoration dec_now = new Decoration();
            XmlNodeList child_nodes = node.ChildNodes;
            foreach (XmlNode child in child_nodes)
            {
                if (child.Name == "storeid") dec_now.storeid = Int32.Parse(child.InnerText);
                else if (child.Name == "attribute_base") dec_now.attribute_base = Int32.Parse(child.InnerText);
                else if (child.Name == "polishtimes") dec_now.polishtimes = Int32.Parse(child.InnerText);
                else if (child.Name == "gold") dec_now.gold = Int32.Parse(child.InnerText);
                else if (child.Name == "name") dec_now.name = child.InnerText;
            }
            int attrib_upgrade = dec_now.attribute_base - dec.attribute_base;
            logInfo(logger, String.Format("炼化[{0}], 属性+{1}", dec_now.name, attrib_upgrade));

            return attrib_upgrade;
        }
        public void destroy(ProtocolMgr protocol, ILogger logger, int magic, Decoration dec, bool is_extra_item)
        {
            string url = "/root/stoneMelt!melt.action";
            string data = String.Format("magic={0}&meltGold=0&gold=0&storeId={1}", magic, dec.storeid);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "融化");
            if (result == null || !result.CmdSucceed) return;
            XmlDocument xml = result.CmdResult;

            int stone_gain = 0;
            XmlNode gain_node = xml.SelectSingleNode("/results/gainbowlder");
            if (gain_node != null) Int32.TryParse(gain_node.InnerText, out stone_gain);

            if (is_extra_item)
                logInfo(logger, String.Format("融化多余的[{0}], 玉石+{1}", dec.name, stone_gain));
            else
                logInfo(logger, String.Format("融化[{0}, 属性+{1}], 玉石+{2}", dec.name, dec.attribute_base, stone_gain));
        }
        public class Decoration
        {
            //<baowu>
            //    <storeid>48501105</storeid>
            //    <name>日月光华</name>
            //    <pic>baowu5</pic>
            //    <attribute_lea>51</attribute_lea>
            //    <attribute_str>47</attribute_str>
            //    <attribute_int>51</attribute_int>
            //    <attribute_base>32</attribute_base>
            //    <quality>5</quality>
            //    <generalname>项羽</generalname>
            //    <bindstatus>0</bindstatus>
            //    <cbtime>-1378700861223</cbtime>
            //    <polishtimes>10</polishtimes>
            //    <polishmax>1</polishmax>
            //    <gold>12</gold>
            //    <equiptype>7</equiptype>
            //    <type>5</type>
            //</baowu>
            public int storeid;
            public int attribute_base;
            public int polishtimes;
            public string name;
            public int gold;
        }
        #endregion

        #region qh
        public int getEquipmentsCanQh(ProtocolMgr protocol, ILogger logger, User user, string qh_idstr)
        {
            string url = "/root/equip!getUpgradeInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取装备强化信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            List<Officer> _officers;
            renderQhInfo(protocol, logger, xml, user, out _officers, qh_idstr);
            return 0;
        }
        /// <summary>
        /// 获取可强化装备(强化界面获得),
        /// 0=success, 1=http failure, 2=no suitable to qh, 10=other
        /// </summary>
        public int handleEquipmentsCanQh(ProtocolMgr protocol, ILogger logger, User user, int silver_available,
            string qh_idstr, int use_assist_silver, int use_gold_silver)
        {
            string url = "/root/equip!getUpgradeInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取装备强化信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            List<Officer> _officers;
            renderQhInfo(protocol, logger, xml, user, out _officers, qh_idstr);

            List<Equipment> _equipsQh = user._qhEquips;
            bool things_done = false;
            List<int> qh_ids = generateIds(qh_idstr);
            foreach (int qh_id in qh_ids)
            {
                Equipment equp = null;
                foreach (Equipment eqp in _equipsQh)
                {
                    if (eqp.Id == qh_id) { equp = eqp; break; }
                }
                if (equp == null || !equp.CanUpgrade) continue;
                if (equp.UpgradeCost > silver_available) continue;
                bool qh_ok = upgradeEquip(protocol, logger, user, _officers, equp,
                    use_gold_silver <= equp.UpgradeCost, use_assist_silver <= equp.UpgradeCost, qh_idstr);
                if (!qh_ok) return 10;

                things_done = true;
                break;
            }
            if (things_done) return 0;
            return 2;
        }
        private void renderQhInfo(ProtocolMgr protocol, ILogger logger, XmlDocument xml, User user,
            out List<Officer> _officers, string qh_idstr)
        {
            _officers = new List<Officer>();
            List<Equipment> _equipsQh = new List<Equipment>();
            tryUseCard(protocol, logger, xml);

            XmlNode magic_node = xml.SelectSingleNode("/results/magic");
            if (magic_node != null)
            {
                int magic = 0;
                Int32.TryParse(magic_node.InnerText, out magic);
                if (magic > 0) user.Magic = magic;
            }
            XmlNode canusegold_node = xml.SelectSingleNode("/results/canusegold");
            if (canusegold_node != null) user.CanUseGoldQh = canusegold_node.InnerText == "1";
            
            XmlNode officer_lists = xml.SelectSingleNode("/results/officerlist");
            if (officer_lists != null)
            {
                XmlNodeList officer_nodes = officer_lists.ChildNodes;
                foreach (XmlNode offnode in officer_nodes)
                {
                    Officer officer = new Officer();
                    foreach (XmlNode cnode in offnode.ChildNodes)
                    {
                        if (cnode.Name == "playerid") officer.Id = Int32.Parse(cnode.InnerText);
                        else if (cnode.Name == "playername") officer.Name = cnode.InnerText;
                        else if (cnode.Name == "pos") officer.Pos = Int32.Parse(cnode.InnerText);
                        else if (cnode.Name == "playerlevel") officer.Level = Int32.Parse(cnode.InnerText);
                        else if (cnode.Name == "ratio") officer.Ratio = float.Parse(cnode.InnerText);
                    }
                    _officers.Add(officer);
                }
            }
            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;
            foreach (XmlNode child in childs)
            {
                if (child.Name != "equip") continue;
                Equipment eqp = new Equipment();
                XmlNodeList eqpchild_list = child.ChildNodes;
                eqp.fillValues(eqpchild_list);
                _equipsQh.Add(eqp);
            }

            List<int> equipids = generateIds(qh_idstr);
            foreach (Equipment eqp in _equipsQh)
            {
                eqp.IsChecked = equipids.IndexOf(eqp.Id) >= 0;
            }
            user._qhEquips = _equipsQh;
        }
        
        /// <summary>
        /// 升级装备
        /// </summary>
        /// <param name="equipId"></param>
        /// <param name="useGold"></param>
        /// <param name="useAssist"></param>
        /// <returns></returns>
        private bool upgradeEquip(ProtocolMgr protocol, ILogger logger, User user, List<Officer> _officers,
            Equipment equip, bool useGold, bool useAssist, string qh_ids)
        {
            if (equip == null) return false;
            int assistId = -1, gold = 0, magic = user.Magic;
            Officer officer = null;
            if (useAssist && _officers.Count > 0)
            {
                officer = _officers[0];
                assistId = officer.Id;
            }
            if (useGold) gold = 100 - magic;
            if (!user.CanUseGoldQh) gold = 0;
            int total_gold = user.Gold;
            if (total_gold < gold)
            {
                logInfo(logger, "你太穷了!!!!!!! 连保证强化装备成功的金币都没有, 等1小时再说强化的事吧");
                return false;
            }

            string url = "/root/equip!upgradeMyEquip.action";
            string data = String.Format("assPlayerId={0}&gold={1}&magic={2}&storeId={3}", assistId, gold, magic, equip.Id);
            int origiEquipLevel = equip.Level;
            if (equip.FragmentCount > 0)
            {
                logInfo(logger, String.Format("装备[{0}]是碎片, 忽略", equip.Name));
                return false;
            }
            int equipCost = equip.UpgradeCost;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "强化装备");
            if (result == null) return false;
            if (!result.CmdSucceed) return false;
            
            XmlDocument xml = result.CmdResult;
            // 有可能是直接返回所有可强化装备(貌似是级别暴击+2时), 有可能是返回下面的结果, 需要判断
            //<results><state>1</state><flag>1</flag><magic>98</magic></results>
            //<results><state>1</state><flag>2</flag><msg>您没有足够的银币</msg></results>
            bool cmd_ok = true;
            XmlNode flag_node = xml.SelectSingleNode("/results/flag");
            if (flag_node != null) cmd_ok = flag_node.InnerText == "1";

            if (!cmd_ok) return false;

            int upgradelevel = 0;
            XmlNode officer_node = xml.SelectSingleNode("/results/officerlist");
            if (officer_node != null)
            {
                renderQhInfo(protocol, logger, xml, user, out _officers, qh_ids);
                Equipment new_eqp = null;
                foreach (Equipment eqp in user._qhEquips)
                {
                    if (eqp.Id == equip.Id) { new_eqp = eqp; break; }
                }
                if (new_eqp != null)
                {
                    int nowlevel = new_eqp.Level;
                    upgradelevel = nowlevel - origiEquipLevel;
                }
            }
            else
            {
                XmlNode magic_node = xml.SelectSingleNode("/results/magic");
                if (magic_node != null)
                {
                    Int32.TryParse(magic_node.InnerText, out magic);
                    if (magic > 0) user.Magic = magic;
                }
                XmlNode canusegold_node = xml.SelectSingleNode("/results/canusegold");
                if (canusegold_node != null) user.CanUseGoldQh = canusegold_node.InnerText == "1";

                XmlNodeList childs = xml.SelectSingleNode("/results").ChildNodes;
                if (officer != null) _officers.Remove(officer);
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "flag") if (child.InnerText == "1") upgradelevel = 1;
                }
            }

            string loginfo = "";
            if (assistId > 0)
            {
                loginfo += String.Format("使用强化辅助: {0}({1}), 降低费用百分比: {2:f2}", officer.Name, officer.Level, officer.Ratio);
                if (_officers.Contains(officer)) _officers.Remove(officer);
            }
            loginfo += String.Format("强化装备 [{0}] {1}, 花费 [{2}]银币", equip.EquipNameWithGeneral, upgradelevel > 0 ? "成功, 级别+" + upgradelevel : "失败", equipCost);
            if (gold > 0) loginfo += String.Format(", 花费金币 [{0}]个", gold);
            logInfo(logger, loginfo);
            return true;
        }
        private class Officer
        {
            public int Id;
            public string Name;
            public int Pos; // 0=王, 1=公, 2=候, 3=伯
            public int Level;
            public float Ratio;
        }
        #endregion

        #region mh
        public bool enchantEquip(ProtocolMgr protocol, ILogger logger, User user, Equipment equip, int mhtype, string mh_ids)
        {
            if (equip == null) return false;
            string url = "/root/enchant!enchant.action";
            string data = String.Format("magic={0}&quantity={1}&storeId={2}&halfBowlder=false&useGold=false", user.Magic, mhtype, equip.Id);
            if (equip.FragmentCount > 0)
            {
                logInfo(logger, String.Format("装备[{0}]是碎片, 忽略", equip.Name));
                return false;
            }
            int equipCost = 0;
            if (mhtype == 1) equipCost = equip.EnchantCost1;
            else if (mhtype == 2) equipCost = equip.EnchantCost2;
            else if (mhtype == 3) equipCost = equip.EnchantCost3;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "魔化装备");
            if (result == null || !result.CmdSucceed) return false;
            if (!result.CmdSucceed) return false;
            
            XmlDocument xml = result.CmdResult;
            renderMhInfo(xml, user, mh_ids);
            // 和获取魔化装备一样的消息, 只是多了一项, /results/enchantingchange, 内容是魔化变化的数值
            XmlNode node = xml.SelectSingleNode("/results/enchantingchange");
            if (node == null) return false;
            int change = 0;
            if (Int32.TryParse(node.InnerText, out change))
            {
                string[] mhtypes = new string[] { "少量", "大量", "海量" };
                string loginfo = String.Format("[{0}]方式魔化化装备[{1}] [{2}{3}], 花费 [{4}] 玉石",
                    mhtypes[mhtype - 1], equip.EquipNameWithGeneral, change > 0 ? "成功+" : "失败", change, equipCost);
                logInfo(logger, loginfo);

                if (change > 0) return true;
                else return false;
            }
            else return false;
        }
        private Equipment findEquip(List<Equipment> equips, int mhid)
        {
            foreach (Equipment eqp in equips)
            {
                if (eqp.Id == mhid) return eqp;
            }
            return null;
        }

        public int getEquipmentsCanMh(ProtocolMgr protocol, ILogger logger, User user, string mh_idstr)
        {
            string url = "/root/enchant!getEnchantEquipsInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取装备魔化信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;

            XmlDocument xml = result.CmdResult;
            renderMhInfo(xml, user, mh_idstr);
            return 0;
        }
        /// <summary>
        /// 获取可强化装备(强化界面获得),
        /// 0=success, 1=http failure, 2=no suitable to mh, 10=other
        /// </summary>
        public int handleEquipmentsCanMh(ProtocolMgr protocol, ILogger logger, User user, string mh_idstr,
            int fail_count_max, string mh_type, int stone_available)
        {
            int result = getEquipmentsCanMh(protocol, logger, user, mh_idstr);

            int mhtype = 1;
            if (mh_type == "少量") mhtype = 1;
            else if (mh_type == "大量") mhtype = 2;
            else if (mh_type == "海量") mhtype = 3;
            List<int> mh_ids = generateIds(mh_idstr);
            if (mh_ids.Count > 0)
            {
                int fail_count = 0;
                while (fail_count < fail_count_max)
                {
                    Equipment equp_target = null;
                    foreach (int mh_id in mh_ids)
                    {
                        Equipment eqp = findEquip(user._mhEquips, mh_id);
                        if (eqp == null || !eqp.CanEnchant) continue;
                        if (eqp.EnchantCost1 > stone_available) continue;
                        if (mhtype == 2 && eqp.EnchantCost2 > stone_available) continue;
                        if (mhtype == 3 && eqp.EnchantCost3 > stone_available) continue;
                        equp_target = eqp;
                        break;
                    }
                    if (equp_target == null) return 2;
                    // mohua
                
                    bool success = enchantEquip(protocol, logger, user, equp_target, mhtype, mh_idstr);
                    if (success) fail_count = 0;
                    else fail_count++;

                    int equipCost = 0;
                    if (mhtype == 1) equipCost = equp_target.EnchantCost1;
                    else if (mhtype == 2) equipCost = equp_target.EnchantCost2;
                    else if (mhtype == 3) equipCost = equp_target.EnchantCost3;
                    stone_available -= equipCost;
                }
                
            }
            return 0;
        }
        private void renderMhInfo(XmlDocument xml, User user, string mh_ids)
        {
            List<Equipment> _equipMh = new List<Equipment>();
            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;
            foreach (XmlNode child in childs)
            {
                if (child.Name != "enchant") continue;
                Equipment eqp = new Equipment();
                XmlNodeList eqpchild_list = child.ChildNodes;
                eqp.fillValues(eqpchild_list);
                _equipMh.Add(eqp);
            }
            List<int> equipids = generateIds(mh_ids);
            foreach (Equipment eqp in _equipMh)
            {
                eqp.IsChecked = equipids.IndexOf(eqp.Id) >= 0;
            }
            user._mhEquips = _equipMh;
        }
        #endregion

        #region weapon
        
        /// <summary>
        /// 获取兵器(兵器界面获得)
        /// 0=success, 1=http failure, 2=no stone/no weapon, 10=other
        /// </summary>
        public int handleWeaponsUpgrade(ProtocolMgr protocol, ILogger logger, User user, bool only_getInfo)
        {
            string weapon_info = "";
            if (user.Level < 120) return 10;
            string url = "/root/troopEquip!getTroopEquipUpgradeInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取兵器信息");
            if (result == null) return 1;
            if(!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;
            tryUseCard(protocol, logger, xml);

            List<Equipment> _equipWeapon = new List<Equipment>();
            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;
            
            int weapon_count = 0, weapon_total_stars = 0; double weapon_total_toughness = 0;
            foreach (XmlNode child in childs)
            {
                if (child.Name != "equip") continue;
                Equipment weapon = new Equipment();
                XmlNodeList eqpchild_list = child.ChildNodes;
                weapon.fillValues(eqpchild_list);
                weapon.goodstype = GoodsType.Weapon;
                _equipWeapon.Add(weapon);
                string color;
                string winfo = renderWeaponInfo(weapon, ref weapon_count, ref weapon_total_stars, ref weapon_total_toughness, out color);
                weapon_info += String.Format("{0}|{1}/", color, winfo);
            }
            weapon_info += String.Format("black|总星级:{0}, 平均星级:{1:f2}/", 
                weapon_total_stars, weapon_total_stars * 1.0 / weapon_count);
            weapon_info += String.Format("black|总坚韧:{0:f2}%, 平均坚韧:{1:f2}%", 
                weapon_total_toughness, weapon_total_toughness / weapon_count);
            user._weapon_info = weapon_info;

            if (only_getInfo) return 0;
            // render weapon info
            // 保留玉石就是为了升级兵器, 所以这里不用再保留玉石
            //int stone_available = getStoneAvailable();
            int stone_available = user.Stone;
            if (stone_available >= 90)
            {
                // 查找是否有可升级的兵器
                bool things_solved = false;
                foreach (Equipment eqp in _equipWeapon)
                {
                    if (!eqp.CanUpgrade) continue;
                    if ((eqp.Level < eqp.CurWeaponLevelLimit && eqp.ZeroStarNum > 0) ||
                        (eqp.Level == eqp.CurWeaponLevelLimit && eqp.Quality == EquipmentQuality.Purple && eqp.ZeroStarNum >= 3 && stone_available >= 270))
                    {
                        upgradeWeapon(protocol, logger, eqp);
                        things_solved = true;
                        break;
                    }
                }
                if (things_solved) return 0;
            }
            return 2;
        }
        /// <summary>
        /// 升级兵器
        /// </summary>
        /// <param name="weaponId"></param>
        /// <returns></returns>
        public bool upgradeWeapon(ProtocolMgr protocol, ILogger logger, Equipment weapon)
        {
            string url = "/root/troopEquip!upgradeMyEquip.action";
            string data = String.Format("storeId={0}&halfBowlder=false", weapon.Id);
            if (weapon == null) return false;
            if (weapon.FragmentCount > 0)
            {
                logInfo(logger, String.Format("兵器[{0}]是碎片, 忽略", weapon.Name));
                return false;
            }
            string desc = "强化兵器";
            if (weapon.Level == weapon.CurWeaponLevelLimit) desc = "补充兵器坚韧度";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null) return false;
            if (!result.CmdSucceed) return false;
            
            XmlDocument xml = result.CmdResult;
            XmlNodeList childs = xml.SelectSingleNode("/results").ChildNodes;
            bool successful = false;
            foreach (XmlNode child in childs)
            {
                if (child.Name == "successupgrade") successful = child.InnerText == "1";
            }
            string loginfo = String.Format("{0} [{1}] {2}", desc, weapon.Name, successful ? "成功" : "失败");
            logInfo(logger, loginfo);
            if (successful) logger.logSurprise(loginfo);
            return true;
        }
        private string renderWeaponInfo(Equipment weapon, ref int weapon_count, ref int weapon_total_stars, ref double weapon_total_tonghness, out string color)
        {
            double toughness, full_toughness; int amount_expect, failcount, needcount;
            WeaponHelper.getWeaponInfo(weapon, 0, out amount_expect, out toughness, out full_toughness, out failcount, out needcount);
            string logt = String.Format("{0}: {1}星  {2}, 失败{3}次",
                weapon.Name.PadLeft(5, '一'),
                weapon.Level.ToString().PadLeft(3),
                weapon.ValueNow.ToString().PadLeft(6),
                failcount.ToString().PadLeft(4));
            if (weapon.Quality == EquipmentQuality.White) color = "gray";
            else if (weapon.Quality == EquipmentQuality.Blue) color = "blue";
            else if (weapon.Quality == EquipmentQuality.Green) color = "green";
            else if (weapon.Quality == EquipmentQuality.Yellow) color = "yellow";
            else if (weapon.Quality == EquipmentQuality.Red) color = "red";
            else
            {
                color = "purple";
                logt = String.Format("{0}:{1}星 {2}, 坚韧{3},满{4},差{5}",
                    weapon.Name.PadLeft(5, '一'), weapon.Level.ToString().PadLeft(3),
                    weapon.ValueNow.ToString().PadLeft(6),
                    String.Format("{0:f2}%", toughness * 100).PadLeft(7),
                    String.Format("{0:f2}%", full_toughness * 100).PadLeft(7),
                    String.Format("{0:f2}%", (full_toughness - toughness) * 100).PadLeft(7));

                weapon_count++;
                weapon_total_stars += weapon.Level;
                weapon_total_tonghness += toughness * 100;
            }
            return logt;
        }
        #endregion

        #region daily weapon
        /// <summary>
        /// 获取每日兵器信息,
        /// 0=success, 1=http failure, 2=got successfully, 3=no this weapon, 10=other
        /// </summary>
        /// <returns></returns>
        public int handleDailyWeapon(ProtocolMgr protocol, ILogger logger, out bool hasGotToday, string target_weapon_name)
        {
            hasGotToday = false;
            Dictionary<string, string> _weaponImages; List<string> _weaponDedicated;
            getDailyWeaponDatabase(out _weaponImages, out _weaponDedicated);
            if (_weaponDedicated.IndexOf(target_weapon_name) < 0) return 3;
            string url = "/root/playerAnswer!getQuestion2.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取每日兵器信息");
            if (result == null) return 1;
            if(!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;
            // 如果今天已经领取过, 那么返回的是 
            // <results><state>1</state><isend>0</isend></results>
            XmlNode isend_node = xml.SelectSingleNode("/results/isend");
            if (isend_node != null)
            {
                hasGotToday = true;
                return 2;
            }

            int max_can_got = 0, now_got = 0;
            XmlNode maxnode = xml.SelectSingleNode("/results/maxrewardtimes");
            if (maxnode != null) Int32.TryParse(maxnode.InnerText, out max_can_got);
            XmlNode gotnode = xml.SelectSingleNode("/results/rewardtimes");
            if (gotnode != null) Int32.TryParse(gotnode.InnerText, out now_got);
            if (max_can_got > 0 && max_can_got == now_got)
            {
                hasGotToday = true;
                return 2;
            }
            else hasGotToday = false;

            // 查看是否已经回答完毕, 可以拿取兵器
            XmlNode can_receive_node = xml.SelectSingleNode("/results/canreceive");
            if (can_receive_node != null && can_receive_node.InnerText == "1")
            {
                string target_weapon_id = "";
                XmlNodeList rewards = xml.SelectNodes("/results/reward");
                foreach (XmlNode reward_node in rewards)
                {
                    Reward re = new Reward();
                    XmlNodeList subs = reward_node.ChildNodes;
                    foreach (XmlNode sub in subs)
                    {
                        if (sub.Name == "type") re.type = sub.InnerText;
                        else if (sub.Name == "name") re.name = sub.InnerText;
                        else if (sub.Name == "quality") re.quality = sub.InnerText;
                        else if (sub.Name == "goodsid") re.goodsid = sub.InnerText;
                    }
                    if (re.name.IndexOf(target_weapon_name) >= 0)
                    {
                        target_weapon_id = re.goodsid;
                        break;
                    }
                }
                if (target_weapon_id != "") if (getDailyWeaponReward(protocol, logger, target_weapon_id)) return 2;
                return 10; // 到此处肯定是出了什么错误, 返回未知错误
            }

            List<string> questions = new List<string>();
            XmlNodeList qu_nodes = xml.SelectNodes("/results/question/pic");
            if (qu_nodes != null && qu_nodes.Count > 0)
            {
                foreach (XmlNode qunode in qu_nodes)
                {
                    if (_weaponImages.ContainsKey(qunode.InnerText))
                        questions.Add(_weaponImages[qunode.InnerText]);
                    else
                    {
                        questions.Add(""); // 找不到, 写到日志中去
                        logInfo(logger, "找不到每日兵器问题的key, 记录在此, key=" + qunode.InnerText);
                    }
                }
            }
            List<Answer> answers = new List<Answer>();
            XmlNodeList ans_nodes = xml.SelectNodes("/results/answer");
            foreach (XmlNode anode in ans_nodes)
            {
                Answer ans = new Answer();
                XmlNodeList option_nodes = anode.ChildNodes;
                foreach (XmlNode optnode in option_nodes) // option node
                {
                    AnswerOption opt = new AnswerOption();
                    XmlNodeList optinner_nodes = optnode.ChildNodes;
                    foreach (XmlNode optinner_node in optinner_nodes)
                    {
                        if (optinner_node.Name == "index") opt.index = optinner_node.InnerText;
                        else if (optinner_node.Name == "name") opt.name = optinner_node.InnerText;
                    }
                    ans.addOption(opt);
                }
                answers.Add(ans);
            }
            List<string> final_answers = new List<string>();
            int index = 0;
            foreach (string question in questions)
            {
                if (answers.Count - 1 >= index) final_answers.Add(answers[index].getAnswerIndex(question));
                index++;
            }
            answerDailyWeaponQuestion(protocol, logger, final_answers);
            return 0;
        }
        /// <summary>
        /// 回答每日兵器问题
        /// </summary>
        /// <param name="weaponIds"></param>
        /// <returns></returns>
        public bool answerDailyWeaponQuestion(ProtocolMgr protocol, ILogger logger, List<string> weaponIds)
        {
            string url = "/root/playerAnswer!answer2.action";
            string answerids = "";
            for (int i = 0, len = weaponIds.Count; i < len; i++)
            {
                answerids += weaponIds[i];
                if (i < len - 1) answerids += ",";
            }
            string data = String.Format("answer={0}", answerids);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "回答每日兵器问题");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            XmlNode all_correct = xml.SelectSingleNode("/results/totalcorrect");
            bool successful = false;
            if (all_correct != null) successful = all_correct.InnerText.Equals("true");
            string loginfo = String.Format("回答每日兵器问题 {0}", successful ? "成功" : "失败");
            logInfo(logger, loginfo);
            return true;
        }
        public bool getDailyWeaponReward(ProtocolMgr protocol, ILogger logger, string weaponId)
        {
            string url = "/root/playerAnswer!receiveFinalReward2.action";
            string data = "giftIndex=" + weaponId;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "获取每日兵器奖励");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            XmlNode reward_name_node = xml.SelectSingleNode("/results/reward");
            XmlNode reward_number_node = xml.SelectSingleNode("/results/rewardnum");
            string rewardname = "", rewardnum = "";
            if (reward_name_node != null) rewardname = reward_name_node.InnerText;
            if (reward_number_node != null) rewardnum = reward_number_node.InnerText;
            string loginfo = String.Format("获取每日兵器奖励 {0}*{1}", rewardname, rewardnum);
            logInfo(logger, loginfo);
            return true;
        }

        #region init image database
        private void getDailyWeaponDatabase(out Dictionary<string, string> _weaponImages, out List<string> _weaponDedicated)
        {
            _weaponImages = new Dictionary<string, string>();

            _weaponImages.Add("sunbinbingfa", "孙膑兵法");
            _weaponImages.Add("guiguzi", "鬼谷子");
            _weaponImages.Add("sunzibingfa", "孙子兵法");
            _weaponImages.Add("luoshenfu", "洛神赋");

            _weaponImages.Add("baiyuqilinbingfu", "白玉麒麟兵符");
            _weaponImages.Add("liulongfeipei", "六龙飞辔"); //六龙飞辔(pei)

            _weaponImages.Add("zhangbashemao", "丈八蛇矛");
            _weaponImages.Add("longlinzijindao", "龙鳞紫金刀");
            _weaponImages.Add("taihejian", "太和剑");
            _weaponImages.Add("qilinshuangqiang", "麒麟双枪");
            _weaponImages.Add("jiuxiaoshennu", "九霄神怒");
            _weaponImages.Add("daxialongque", "大夏龙雀");
            _weaponImages.Add("16101", "雪霁");
            _weaponImages.Add("danxiabiri", "丹霞蔽日");

            _weaponImages.Add("tongyunjiao", "彤云角");
            _weaponImages.Add("hongyijiangjunpao", "红衣将军炮");
            _weaponImages.Add("huagucongji", "化骨丛棘");
            _weaponImages.Add("shilvyan", "弑履岩");
            _weaponImages.Add("yulinjinghui", "玉麟旌麾"); // 玉麟旌(jing)麾
            _weaponImages.Add("tongrenjiliche", "铜人计里车");
            _weaponImages.Add("huaguxuandeng", "化骨悬灯");

            _weaponImages.Add("xuantingjiao", "玄霆角");
            _weaponImages.Add("wudijiangjunpao", "无敌将军炮");
            _weaponImages.Add("wuduwenxinding", "五毒问心钉");
            _weaponImages.Add("qilufeng", "七戮锋");
            _weaponImages.Add("panlonghuagai", "蟠龙华盖"); // 蟠(pan)龙华盖
            _weaponImages.Add("xuanyuanzhinanche", "轩辕指南车");
            _weaponImages.Add("luohunmingdeng", "落魂冥灯");

            _weaponImages.Add("dayelonglinjia", "大叶龙鳞甲");
            _weaponImages.Add("xuanwukai", "玄武铠");
            _weaponImages.Add("26101", "三味纯阳铠");
            _weaponImages.Add("yulvjindaijia", "玉镂金带甲"); // 玉镂(lou)金带甲

            _weaponImages.Add("xianglong", "象龙");
            _weaponImages.Add("menghu", "猛虎");
            _weaponImages.Add("xiongshi", "雄狮");
            _weaponImages.Add("zhanxiang", "战象");
            _weaponImages.Add("qibu", "七步");
            _weaponImages.Add("qilin", "麒麟");

            _weaponImages.Add("fengyulongfeipifeng", "凤羽龙飞披风");
            _weaponImages.Add("45101", "千手叶檀披风");
            _weaponImages.Add("46101", "蝶凤舞阳");

            _weaponDedicated = new List<string>();
            _weaponDedicated.Add("彤云角");
            _weaponDedicated.Add("红衣将军炮");
            _weaponDedicated.Add("化骨丛棘");
            _weaponDedicated.Add("弑履岩");
            _weaponDedicated.Add("玉麟旌麾"); // 玉麟旌(jing)麾
            _weaponDedicated.Add("铜人计里车");
            _weaponDedicated.Add("化骨悬灯");

            _weaponDedicated.Add("玄霆角");
            _weaponDedicated.Add("无敌将军炮");
            _weaponDedicated.Add("五毒问心钉");
            _weaponDedicated.Add("七戮锋");
            _weaponDedicated.Add("蟠龙华盖"); // 蟠(pan)龙华盖
            _weaponDedicated.Add("轩辕指南车");
            _weaponDedicated.Add("落魂冥灯");
        }
        #endregion

        private class AnswerOption
        {
            public string index;
            public string name;
        }
        private class Answer
        {
            private List<AnswerOption> _options = new List<AnswerOption>();
            public void addOption(AnswerOption opt) { _options.Add(opt); }
            public string getAnswerIndex(string question)
            {
                string answer = "0"; int index = 0;
                foreach (AnswerOption opt in _options)
                {
                    if (opt.name.IndexOf(question) >= 0)
                    {
                        answer = opt.index;
                        break;
                    }
                    index++;
                }
                return answer;
            }
        }
        private class Reward
        {
            public string type;
            public string name;
            public string goodsid;
            public string quality;
        }
        #endregion

        #region merchants
        /// <summary>
        /// 获取委派商人,
        /// 0=success, 1=http failure, 2=not enough silver, 3=work done today, 10=other
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <param name="silver_available"></param>
        /// <param name="only_free"></param>
        /// <param name="merchant_type"></param>
        /// <param name="sell_quality">白色/...</param>
        /// <returns></returns>
        public int handleMerchants(ProtocolMgr protocol, ILogger logger, int silver_available, bool only_free,
            string merchant_type, string sell_quality)
        {
            List<Merchant> _allMerchants = new List<Merchant>();
            int _merchantCd = 0; bool _merchantCdFlag = false;
            bool _haveFree = false;

            string url = "/root/market!getPlayerMerchant.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取委派商人信息");
            if (result == null) return 1;
            if(!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            XmlNode cd_node = xml.SelectSingleNode("/results/cd");
            if (cd_node != null) _merchantCd = Int32.Parse(cd_node.InnerText);

            XmlNode cdflag_node = xml.SelectSingleNode("/results/cdflag");
            if (cdflag_node != null) _merchantCdFlag = cdflag_node.InnerText == "1";

            XmlNode free_node = xml.SelectSingleNode("/results/free");
            if (free_node != null) _haveFree = free_node.InnerText == "1";

            XmlNodeList merchant_nodes = xml.SelectNodes("/results/merchant");
            foreach (XmlNode merchant_node in merchant_nodes)
            {
                Merchant m = new Merchant();
                XmlNodeList childs = merchant_node.ChildNodes;
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "merchantid") m.merchantid = Int32.Parse(child.InnerText);
                    else if (child.Name == "merchantname") m.merchantname = child.InnerText;
                    else if (child.Name == "cost") m.cost = Int32.Parse(child.InnerText);
                }
                _allMerchants.Add(m);
            }

            // start do things
            if (only_free && !_haveFree) return 3;
            if (_merchantCdFlag && _merchantCd > 2000) return _merchantCd;

            Merchant temp_merchant = null;
            if (merchant_type.Equals("马"))
            {
                foreach (Merchant m in _allMerchants)
                {
                    if (m.merchantid > 4) continue;
                    if (temp_merchant == null) temp_merchant = m;
                    else if (temp_merchant.merchantid < m.merchantid) temp_merchant = m;
                }
            }
            else // 披风
            {
                foreach (Merchant m in _allMerchants)
                {
                    if (m.merchantid <= 4) continue;
                    if (temp_merchant == null) temp_merchant = m;
                    else if (temp_merchant.merchantid < m.merchantid) temp_merchant = m;
                }
            }
            if (temp_merchant.cost > silver_available) return 2;
            int trade_result = tradeMerchant(protocol, logger, temp_merchant, sell_quality);
            if (trade_result == 0) return 0;
            return 10;
        }
        /// <summary>
        /// 委派
        /// </summary>
        /// <param name="merchantId">1-4为马, 5-8为披风</param>
        /// <returns></returns>
        public int tradeMerchant(ProtocolMgr protocol, ILogger logger, Merchant merchant, string sell_quality)
        {
            string url = "/root/market!trade.action";
            string data = String.Format("gold=0&merchantId={0}", merchant.merchantid);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "委派" + merchant.merchantname);
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            
            XmlDocument xml = result.CmdResult;

            string[] quality_names = new string[] { "白色", "蓝色", "绿色", "黄色", "红色", "紫色" };
            int sell_quality_index = 0;
            for (int i = 0; i < quality_names.Length; i++)
            {
                if (quality_names[i].Equals(sell_quality))
                {
                    sell_quality_index = i + 1;
                    break;
                }
            }

            string tradeSN = "", name = ""; int quality = 0, sell_price = 0; bool isChip = false;

            XmlNode sn_node = xml.SelectSingleNode("/results/tradesn");
            if (sn_node != null) tradeSN = sn_node.InnerText;

            XmlNode merchandise_node = xml.SelectSingleNode("/results/merchandise");
            XmlNodeList childs = merchandise_node.ChildNodes;
            foreach (XmlNode child in childs)
            {
                if (child.Name == "merchandisename") name = child.InnerText;
                else if (child.Name == "merchandisequality") quality = Int32.Parse(child.InnerText);
                else if (child.Name == "cost") sell_price = Int32.Parse(child.InnerText);
                else if (child.Name == "chip") isChip = true;
            }
            string loginfo = String.Format("委派[{0}], 花费{1}银币, 获得[{2}{3}], 售价{4}银币",
                merchant.merchantname, merchant.cost, name, isChip ? "碎片" : "", sell_price);
            logInfo(logger, loginfo);
            if (quality <= sell_quality_index) sellMerchantGoods(protocol, logger, tradeSN, name);
            return 0;
        }
        /// <summary>
        /// 卖出委派物品
        /// </summary>
        /// <param name="tradeSN"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool sellMerchantGoods(ProtocolMgr protocol, ILogger logger, string tradeSN, string name)
        {
            string url = "/root/market!confirm.action";
            string data = String.Format("tradeSN={0}", tradeSN);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "卖出委派物品");
            if (result == null || !result.CmdSucceed) return false;
            //<results><state>1</state><usesize>21</usesize><cost>3750</cost></results>
            XmlDocument xml = result.CmdResult;
            XmlNode cost_node = xml.SelectSingleNode("/results/cost");
            int cost = Int32.Parse(cost_node.InnerText);
            string loginfo = String.Format("卖出委派物品 [{0}], 银币+{1}", name, cost);
            logInfo(logger, loginfo);
            return true;
        }
        /// <summary>
        /// 委派商人
        /// </summary>
        public class Merchant
        {
            //<merchant>
            //  <merchantid>1</merchantid> 马=1/2/3/4, 披风=5/6/7/8
            //  <merchantname>普通马商</merchantname>
            //  <merchantintro>委派得到各种名马，并有机会出现高级马商。</merchantintro>
            //  <cost>8000</cost>
            //  <nextcharge>40</nextcharge>
            //</merchant>
            public int merchantid;
            public string merchantname;
            public int cost; // 银币
        }
        #endregion
    }
}
